import { PrismaService } from '@app/prisma';
import { ResponsibleOrderEntity } from '@app/prisma/entitys/ResponsibleOrder.entity';
import { OrderEntity } from '@app/prisma/entitys/order.entity';
import { UserEntity } from '@app/prisma/entitys/user.entity';
import { UseGuards } from '@nestjs/common';
import { Args, Int, Mutation, Query, Resolver } from '@nestjs/graphql';
import { GqlAuthGuard, GqlCurrentUser } from 'src/auth/auth.guard';

@Resolver()
export class OrderResolver {
    constructor(
        private readonly prismaService: PrismaService
    ) { }

    @Mutation(() => OrderEntity)
    @UseGuards(GqlAuthGuard)
    payShop(
        @Args("shop", { type: () => Int }) shop: number,
        @Args("ids", { type: () => [Int] }) ids: number[],
        @GqlCurrentUser() user: UserEntity
    ) {
        const keys = ids.reduce((acc, id) => {
            if (!acc[id]) acc[id] = 0;
            acc[id]++;
            return acc;
        }, {})
        const data: {
            count: number,
            goodsId: number
        }[] = Object.keys(keys).map((key) => ({ count: keys[key], goodsId: Number(key) }));
        return this.prismaService.order.create({
            data: {
                shop: {
                    connect: {
                        id: shop
                    }
                },
                status: "待付款",
                OrderOnGoods: {
                    createMany: {
                        data
                    }
                },
                user: {
                    connect: {
                        id: user.id
                    }
                }
            }
        })
    }

    @Query(() => OrderEntity)
    @UseGuards(GqlAuthGuard)
    getOrderDetial(
        @Args("id", { type: () => Int }) id: number
    ) {
        return this.prismaService.order.findUniqueOrThrow({
            where: {
                id
            },
            include: {
                OrderOnGoods: {
                    include: {
                        goods: true
                    }
                },
                shop: true,
                user: true
            }
        })
    }

    @Mutation(() => OrderEntity)
    @UseGuards(GqlAuthGuard)
    orderPay(
        @Args("id", { type: () => Int }) id: number
    ) {
        return this.prismaService.order.update({
            where: {
                id
            },
            data: {
                status: "待配送"
            }
        })
    }

    @Query(() => [OrderEntity])
    @UseGuards(GqlAuthGuard)
    getSelfOrder(
        @GqlCurrentUser() user: UserEntity
    ) {
        return this.prismaService.order.findMany({
            where: {
                userId: user.id
            },
            include: {
                OrderOnGoods: {
                    include: {
                        goods: true
                    }
                },
                shop: true
            },
            orderBy: {
                id: "desc"
            }
        })
    }

    @Mutation(() => OrderEntity)
    @UseGuards(GqlAuthGuard)
    delSelfOrder(
        @Args("id", { type: () => Int }) id: number,
        @GqlCurrentUser() user: UserEntity
    ) {
        return this.prismaService.order.delete({
            where: {
                id,
                status: "已完成",
                userId: user.id
            },
        })
    }

    @Mutation(() => OrderEntity)
    @UseGuards(GqlAuthGuard)
    async receivingOrder(
        @Args("id", { type: () => Int }) id: number,
        @GqlCurrentUser() user: UserEntity
    ) {
        const order = await this.prismaService.order.findUniqueOrThrow({
            where: { id }
        })
        const shop = await this.prismaService.shop.findUnique({ where: { id: order.shopId } });
        await this.prismaService.shop.update({
            where: {
                id: shop.id
            },
            data: {
                count: shop.count + 1
            }
        })
        return await this.prismaService.order.update({
            where: {
                id,
                status: "待收货",
                userId: user.id
            },
            data: {
                status: "已完成"
            }
        })
    }

    @Mutation(() => OrderEntity)
    @UseGuards(GqlAuthGuard)
    async deliveryOrder(
        @Args("id", { type: () => Int }) id: number,
        @GqlCurrentUser() user: UserEntity
    ) {
        const order = await this.prismaService.order.findUniqueOrThrow({
            where: {
                id
            },
            include: {
                shop: true,
                OrderOnGoods: {
                    include: {
                        goods: true
                    }
                }
            }
        })
        const count = order.OrderOnGoods.reduce((count, item) => count + item.count, 0);
        const total = order.OrderOnGoods.reduce((total, item) => total + item.count * item.goods.price, 0) + order.shop.threshold;
        await this.prismaService.responsibleOrder.create({
            data: {
                total,
                count,
                shop: {
                    connect: {
                        id: order.shopId
                    }
                },
                order: {
                    connect: {
                        id: order.id
                    }
                },
                user: {
                    connect: {
                        id: user.id
                    }
                },
                money: order.shop.threshold
            }
        })
        return await this.prismaService.order.update({
            where: {
                id,
                status: "待配送"
            },
            data: {
                status: "待收货"
            }
        })
    }

    @Query(() => [ResponsibleOrderEntity])
    @UseGuards(GqlAuthGuard)
    getSelfResOrder(
        @GqlCurrentUser() user: UserEntity
    ) {
        return this.prismaService.responsibleOrder.findMany({
            where: {
                userId: user.id
            },
            include: {
                shop: true
            },
            orderBy: {
                id: "desc"
            }
        })
    }

    @Query(() => [OrderEntity])
    selALlOrder() {
        return this.prismaService.order.findMany({
            orderBy: {
                id: "desc"
            },
            include: {
                OrderOnGoods: {
                    include: {
                        goods: true
                    }
                },
                shop: true,
                user: true
            }
        })
    }

    @Query(() => [OrderEntity])
    @UseGuards(GqlAuthGuard)
    getSelfAllOrder(
        @GqlCurrentUser() user: UserEntity
    ) {
        return this.prismaService.order.findMany({
            where: {
                shop: {
                    phone: user.account
                }
            },
            orderBy: {
                id: "desc"
            },
            include: {
                OrderOnGoods: {
                    include: {
                        goods: true
                    }
                },
                shop: true,
                user: true
            }
        })
    }
}
